GitHubで管理しているリポジトリの移譲先の調べ方を考えてみた
こんにちは。サービスグループの武田です。
GitHubを利用してリポジトリ管理をしている場合、そのリポジトリのオーナーを変更できます。機能としては リポジトリの移譲 として提供されています。
普段使用している分には移譲されたかどうかは気にする必要はありません。ブラウザからアクセスすると自動でリダイレクトされますし、git clone
などコマンドで操作する際にも特に意識することなく動作するためです。とはいえ、自分たちで管理しているリポジトリを移譲したら、ローカルリポジトリの参照先などは変更後のURLに変えておきたいですよね。
そんなわけで、今回はリポジトリが移譲されたのか。されていた場合は変更後のURLはどこなのか。を取得する方法を考えてみました。
環境
次のような環境で検証しています。
$ sw_vers ProductName: Mac OS X ProductVersion: 10.15.4 BuildVersion: 19E287 $ curl --version curl 7.64.1 (x86_64-apple-darwin19.0) libcurl/7.64.1 (SecureTransport) LibreSSL/2.8.3 zlib/1.2.11 nghttp2/1.39.2 Release-Date: 2019-03-27 Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp Features: AsynchDNS GSS-API HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz MultiSSL NTLM NTLM_WB SPNEGO SSL UnixSockets
パブリックリポジトリ
まずはパブリックリポジトリから考えてみます。
ブラウザでアクセスしてみる
一番簡単なのはブラウザを起動してアクセスしてみることです。一例としてhttps://github.com/defunkt/hub
にアクセスしてみるとhttps://github.com/github/hub
にリダイレクトされます。簡単ですね。
curlコマンドでURLをたたいてみる
GUIではなくCUIで調べたい!という方もいますよね。わかります。上記と同じURLにcurlでアクセスしてみましょう。
$ curl https://github.com/defunkt/hub -o /dev/null -D - -s HTTP/1.1 301 Moved Permanently date: Mon, 20 Apr 2020 00:00:00 GMT content-type: text/html; charset=utf-8 server: GitHub.com status: 301 Moved Permanently vary: X-PJAX, Accept-Encoding, Accept, X-Requested-With location: https://github.com/github/hub cache-control: no-cache strict-transport-security: max-age=31536000; includeSubdomains; preload x-frame-options: deny x-content-type-options: nosniff x-xss-protection: 1; mode=block referrer-policy: origin-when-cross-origin, strict-origin-when-cross-origin expect-ct: max-age=2592000, report-uri="https://api.github.com/_private/browser/errors" content-security-policy: default-src 'none'; base-uri 'self'; block-all-mixed-content; connect-src 'self' uploads.github.com www.githubstatus.com collector.githubapp.com api.github.com www.google-analytics.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com cdn.optimizely.com logx.optimizely.com/v1/events wss://live.github.com; font-src github.githubassets.com; form-action 'self' github.com gist.github.com; frame-ancestors 'none'; frame-src render.githubusercontent.com; img-src 'self' data: github.githubassets.com identicons.github.com collector.githubapp.com github-cloud.s3.amazonaws.com *.githubusercontent.com; manifest-src 'self'; media-src 'none'; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com Content-Length: 95
ステータスコードとlocationヘッダで確認できますね。情報量が多いという場合は-w
オプションで絞ることもできます。
$ curl https://github.com/defunkt/hub -o /dev/null -s -w '%{http_code}\n%{redirect_url}\n' 301 https://github.com/github/hub
GitHub APIをたたいてみる
CUIで確認するもうひとつの方法としてGitHub APIの利用が考えられます。実際にたたいてみましょう。
$ curl https://api.github.com/repos/defunkt/hub { "message": "Moved Permanently", "url": "https://api.github.com/repositories/401025", "documentation_url": "https://developer.github.com/v3/#http-redirects" }
移譲されていないリポジトリの場合は、リポジトリの情報が大量に取得できるのですが、移譲されている場合はシンプルな結果が取得できます。url
フィールドのエンドポイントを追加でたたいてみます(結果が長いので一部だけ取り出します)。
$ curl https://api.github.com/repositories/401025 -s | jq -r '.html_url' https://github.com/github/hub
まさしく欲しかったURLが取得できました。
プライベートリポジトリ
パブリックリポジトリの場合は比較的容易に調べられました。ではプライベートリポジトリではどうでしょうか。GUIでよければ、GitHubにログインした状態でアクセスしてみれば大丈夫です。問題はCUIです。
curlで普通にリポジトリのURLをたたいても 404 になります。認証していないのでしかたないです。ということでアクセストークンを利用することになります *1。トークンの作成については次のドキュメントを参考にしてください。
コマンドライン用の個人アクセストークンを作成する - GitHub ヘルプ
GitHub APIをたたいてみる
ヘッダにトークンを追加するだけで、基本的にはパブリックリポジトリの場合と同じです(リポジトリ名などは架空です)。
$ curl -H 'Authorization: token xxx' https://api.github.com/repos/TAKEDA-Takashi/private-repo -o /dev/null -s -w '%{http_code}\n%{redirect_url}\n' 301 https://api.github.com/repositories/123456789 $ curl https://api.github.com/repositories/123456789 -s | jq -r '.html_url' https://github.com/TAKEDA-Takashi2/private-repo
シンプルに取得できましたね。
GraphQLを使ってみる
せっかくアクセストークンを作成したので、おまけでGraphQLを使ってみました。GraphQLを使用するためにはパブリックリポジトリであっても認証が必要です。JSON内の文字列では改行できませんが、見やすくするためtr
を使って強引に整形しています(一行で書く場合は不要です)。
$ curl -H 'Authorization: token xxx' -X POST -d "$(echo ' { "query": "query { repository(owner:\"defunkt\", name:\"hub\") { url, sshUrl } }" } ' | tr -d '\n')" https://api.github.com/graphql {"data":{"repository":{"url":"https://github.com/github/hub","sshUrl":"git@github.com:github/hub.git"}}}
GraphQLを使うと直接移譲後のURLが取得できるんですね。なるほど。
まとめ
複数のリポジトリを段階的に移譲してく必要があり、ローカルリポジトリの参照先URLを変更する事前チェックの方法として考えてみました。誰かの助けになれば幸いです。
脚注
- ベーシック認証での認証も可能ですが推奨されません ↩